﻿using System;
using System.Collections.Generic;

namespace BizElements.Core
{
    /// <summary>Entity validator factory creates <see cref="IEntityValidator"/> objects for provided entities. You may register custom validators.</summary>
    /// <remarks><para>By default, the factory checks if an entity implements <see cref="IEntityValidator"/> interface, i.e. if it can validate itself. 
    /// If not then a default or custom <see cref="IEntityValidator"/> object is created that validates entity fields.</para></remarks>
    public static class EntityValidatorFactory
    {
        static readonly Type DefaultValidatorClass = typeof(EntityValidator);
        static readonly Dictionary<string, Type> ValidatorMap = new Dictionary<string, Type>();

        /// <summary>Registers custom validator for entities mapped to the specified table/view name.</summary>
        /// <typeparam name="T">A class that implements <see cref="IEntityValidator"/> interface and has a default/parameterless constructor.</typeparam>
        /// <param name="tableName">Table/view name.</param>
        public static void RegisterValidator<T>(string tableName)
            where T : class, IEntityValidator, new()
        {
            ValidatorMap[tableName] = typeof(T);
        }

        /// <summary>Gets validator object that provides field validation services for the specified entity.</summary>
        /// <param name="entity">Entity. If it implements IEntityValidator then it is returned by the method.</param>
        /// <returns>Vaidator.</returns>
        public static IEntityValidator GetValidator(IEntity entity)
        {
            // Entity may handle validation on its own. E.g. classes which derive from EntityModelBase.
            IEntityValidator validator = entity as IEntityValidator;
            if (validator != null)
                return validator;

            Type validatorClass;
            ValidatorMap.TryGetValue(entity.Table.TableName, out validatorClass);
            if (validatorClass == null)
                validatorClass = DefaultValidatorClass;

            validator = (IEntityValidator)Activator.CreateInstance(validatorClass);
            validator.ValidatedEntity = entity;
            return validator;
        }
    }
}
